﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace UniPie
{
	/// <summary>
	/// The PieSlice user control.
	/// </summary>
	public partial class PieSlice : UserControl , INotifyPropertyChanged
	{
		/// <summary>
		/// The possible slice shapes.
		/// </summary>
		public enum SliceShapes
		{
			Center,
			Inner8,
			Outer8
		}

		public PieSlice()
		{
			InitializeComponent();
		}

//##################################################################
#region Properties

		/// <summary>
		/// Slice definition property.
		/// 
		/// The slice definition driving this slice.
		/// </summary>
		[Category("Common")]
		public SliceDefinition Definition
		{
			get { return (SliceDefinition)this.GetValue(DefinitionProperty); }
			set
			{
				if (value != this.Definition)
				{
					this.SetValue(DefinitionProperty, value);
					HandlePropertyChanged("Definition");
				}
			}
		}

		public static readonly DependencyProperty DefinitionProperty = DependencyProperty.Register(
			"Definition",
			typeof(SliceDefinition),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.DefinitionChanged));

		private static void DefinitionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			PieSlice ps = d as PieSlice;

			if (ps != null)
			{
				ps.HandlePropertyChanged(e.Property.ToString());
			}
		}

		/// <summary>
		/// Shape property.
		/// </summary>
		[Category("Common")]
		public SliceShapes Shape
		{
			get { return (SliceShapes)this.GetValue(ShapeProperty); }
			set
			{
				if (value != this.Shape)
				{
					this.SetValue(ShapeProperty, value);
					HandlePropertyChanged("Shape");
				}
			}
		}

		public static readonly DependencyProperty ShapeProperty = DependencyProperty.Register(
			"Shape",
			typeof(SliceShapes),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.ShapeChanged));

		private static void ShapeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}
		
		/// <summary>
		/// IsSelected property.
		/// </summary>
		[Category("Common")]
		public bool IsSelected
		{
			get { return (bool)this.GetValue(IsSelectedProperty); }
			set
			{
				if (value != this.IsSelected)
				{
					this.SetValue(IsSelectedProperty, value);
					HandlePropertyChanged("IsSelected");
				}
			}
		}

		public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
			"IsSelected",
			typeof(bool),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.IsSelectedChanged));

		private static void IsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

		/// <summary>
		/// Text Placement Radial property.
		/// </summary>
		[Category("Common")]
		public bool TextPlacementRadial
		{
			get { return (bool)this.GetValue(TextPlacementRadialProperty); }
			set
			{
				if (value != this.TextPlacementRadial)
				{
					this.SetValue(TextPlacementRadialProperty, value);
					HandlePropertyChanged("TextPlacementRadial");
				}
			}
		}

		public static readonly DependencyProperty TextPlacementRadialProperty = DependencyProperty.Register(
			"TextPlacementRadial",
			typeof(bool),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.TextPlacementRadialChanged));

		private static void TextPlacementRadialChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

		/// <summary>
		/// Text flipped property.
		/// </summary>
		[Category("Common")]
		public bool TextFlipped
		{
			get { return (bool)this.GetValue(TextFlippedProperty); }
			set
			{
				if (value != this.TextFlipped)
				{
					this.SetValue(TextFlippedProperty, value);
					HandlePropertyChanged("TextFlipped");
				}
			}
		}

		public static readonly DependencyProperty TextFlippedProperty = DependencyProperty.Register(
			"TextFlipped",
			typeof(bool),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.TextFlippedChanged));

		private static void TextFlippedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

		/// <summary>
		/// Preview mode property.
		/// </summary>
		[Category("Common")]
		public bool PreviewMode
		{
			get { return (bool)this.GetValue(PreviewModeProperty); }
			set
			{
				if (value != this.PreviewMode)
				{
					this.SetValue(PreviewModeProperty, value);
					HandlePropertyChanged("PreviewMode");
				}
			}
		}

		public static readonly DependencyProperty PreviewModeProperty = DependencyProperty.Register(
			"PreviewMode",
			typeof(bool),
			typeof(PieSlice),
			new UIPropertyMetadata(PieSlice.PreviewModeChanged));

		private static void PreviewModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

#endregion

//##################################################################
#region Event handlers

		/// <summary>
		/// 
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Notifies the property changed.
		/// </summary>
		/// <param name="property">The property.</param>
		private void HandlePropertyChanged(string property)
		{
			PropertyChangedEventHandler handler = PropertyChanged;

			switch (property)
			{
				case "Definition":
					UpdateVisualStates();				
					break;

				case "IsSelected":
					UpdateVisualStates();
					break;

				default:
					break;
			}

			if (handler != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(property));
			}
		}

		/// <summary>
		/// Handles the Slice_Loaded event.
		/// </summary>
		private void Slice_Loaded(object sender, RoutedEventArgs e)
		{
			VisualStateManager.GoToState(this, Shape.ToString(), false);
		}

		/// <summary>
		/// Handles the Slice_MouseEnter event.
		/// </summary>
		private void Slice_MouseEnter(object sender, MouseEventArgs e)
		{
			if (!PreviewMode)
			{
				if (Definition.IsEnabled)
				{
					VisualStateManager.GoToState(this, "Selected", false);
				}
				IsSelected = true;
			}
		}

		/// <summary>
		/// Handles the Slice_MouseLeave event.
		/// </summary>
		private void Slice_MouseLeave(object sender, MouseEventArgs e)
		{
			if (!PreviewMode)
			{
				if (Definition.IsEnabled)
				{
					VisualStateManager.GoToState(this, "Unselected", false);
				}
				IsSelected = false;
			}
		}

		/// <summary>
		/// Handles the Slice_MouseUp event.
		/// </summary>
		private void Slice_MouseUp(object sender, MouseButtonEventArgs e)
		{
			if (PreviewMode)
			{
				IsSelected = true;
			}
		}
#endregion

		/// <summary>
		/// Updates the visual states so they match the related properties.
		/// </summary>
		public void UpdateVisualStates()
		{
			if (Definition != null)
			{
				if (Definition.IsEnabled)
				{
					if (IsSelected)
					{
						if (PreviewMode)
						{
							VisualStateManager.GoToState(this, "Unselected", false);
							VisualStateManager.GoToState(this, "Editing", false);
						}
						else
						{
							VisualStateManager.GoToState(this, "Selected", false);
							VisualStateManager.GoToState(this, "NotEditing", false);
						}
					}
					else
					{
						VisualStateManager.GoToState(this, "Unselected", false);
						VisualStateManager.GoToState(this, "NotEditing", false);
					}
				}
				else
				{
					if (IsSelected && PreviewMode)
					{
						VisualStateManager.GoToState(this, "Disabled", false);
						VisualStateManager.GoToState(this, "Editing", false);
					}
					else
					{
						VisualStateManager.GoToState(this, "Disabled", false);
						VisualStateManager.GoToState(this, "NotEditing", false);
					}
				}
			}
		}
	}
}